package com.aizuda.boot.modules.business.contract.service.impl;

import com.aizuda.boot.modules.business.contract.entity.ContractWorkflowDepartment;
import com.aizuda.boot.modules.business.contract.entity.ContractWorkflowEntity;
import com.aizuda.boot.modules.business.contract.entity.ContractWorkflowTypeEntity;
import com.aizuda.boot.modules.business.contract.entity.dto.ProcessKeyTypeCache;
import com.aizuda.boot.modules.business.contract.mapper.ContractWorkflowMapper;
import com.aizuda.boot.modules.business.contract.service.ContractWorkflowDepartmentService;
import com.aizuda.boot.modules.business.contract.service.ContractWorkflowService;
import com.aizuda.boot.modules.business.contract.service.ContractWorkflowTypeService;
import com.aizuda.boot.modules.common.constant.RedisKeyConstant;
import com.aizuda.boot.modules.common.util.RedisService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * 合同流程Service实现类
 *
 * @Author sangyirong
 * @Version 1.0
 * @Date 2025/5/20 13:36
 */
@Slf4j
@Service
public class ContractWorkflowServiceImpl extends ServiceImpl<ContractWorkflowMapper, ContractWorkflowEntity> implements ContractWorkflowService {

    @Autowired
    private ContractWorkflowTypeService contractWorkflowTypeService;

    @Autowired
    private ContractWorkflowDepartmentService contractWorkflowDepartmentService;

    @Resource
    private RedisService redisService;

    @Override
    public Long selectOptimalWorkflowId(Integer contractTypeId, Long userDepartmentId) {
        if (contractTypeId == null) {
            log.warn("合同类型ID为空，无法选择工作流");
            return null;
        }

        try {
            log.info("审批工作流匹配 - 只根据合同类型匹配，不考虑部门。合同类型ID: {}", contractTypeId);

            // 1. 根据合同类型ID查找对应的工作流ID列表
            List<ContractWorkflowTypeEntity> workflowTypes = contractWorkflowTypeService.list(
                    new LambdaQueryWrapper<ContractWorkflowTypeEntity>()
                            .eq(ContractWorkflowTypeEntity::getContractTypeId, contractTypeId)
            );

            if (CollectionUtils.isEmpty(workflowTypes)) {
                log.info("未找到合同类型对应的工作流，合同类型ID: {}", contractTypeId);
                return null;
            }

            // 2. 获取所有workflowId
            List<Long> workflowIds = workflowTypes.stream()
                    .map(ContractWorkflowTypeEntity::getWorkflowId)
                    .collect(Collectors.toList());

            log.info("找到 {} 个候选工作流ID: {}", workflowIds.size(), workflowIds);

            // 3. 查询所有对应的工作流（已启用的），按优先级排序，不再考虑部门匹配
            List<ContractWorkflowEntity> workflows = this.list(
                    new LambdaQueryWrapper<ContractWorkflowEntity>()
                            .in(ContractWorkflowEntity::getId, workflowIds)
                            .eq(ContractWorkflowEntity::getIsEnabled, true)
                            .orderByDesc(ContractWorkflowEntity::getPriority)
            );

            if (CollectionUtils.isEmpty(workflows)) {
                log.info("未找到已启用的工作流，合同类型ID: {}", contractTypeId);
                return null;
            }

            // 4. 直接选择优先级最高的工作流（不再考虑部门匹配）
            ContractWorkflowEntity selectedWorkflow = workflows.get(0);
            log.info("成功选择审批工作流，合同类型ID: {}, 工作流ID: {}, 名称: {}, 优先级: {}",
                    contractTypeId, selectedWorkflow.getId(), selectedWorkflow.getWorkflowName(), selectedWorkflow.getPriority());
            return selectedWorkflow.getId();

        } catch (Exception e) {
            log.error("选择最优工作流失败，合同类型ID: {}", contractTypeId, e);
            return null;
        }
    }

    @EventListener(ApplicationReadyEvent.class)
    public void initTypeProcess() {
        log.info("初始化合同类型对应的流程");
        List<ContractWorkflowTypeEntity> contractWorkflowTypes = contractWorkflowTypeService.list();
        if (CollectionUtils.isEmpty(contractWorkflowTypes)) {
            log.info("没有合同类型对应的流程");
            return;
        }
        List<Long> workflowIds = contractWorkflowTypes.stream().map(ContractWorkflowTypeEntity::getWorkflowId).distinct().toList();
        List<ContractWorkflowEntity> contractWorkflowEntities = this.listByIds(workflowIds);
        if (CollectionUtils.isEmpty(contractWorkflowEntities)) {
            log.info("没有合同流程");
            return;
        }
        Map<Integer, List<ContractWorkflowTypeEntity>> typeMap = contractWorkflowTypes.stream().collect(Collectors.groupingBy(ContractWorkflowTypeEntity::getContractTypeId));
        typeMap.forEach((contractTypeId, contractWorkflowTypeEntities) -> {
            List<Long> typeWorkflowIds = contractWorkflowTypeEntities.stream().map(ContractWorkflowTypeEntity::getWorkflowId).distinct().toList();
            Optional<ContractWorkflowEntity> first = contractWorkflowEntities.stream()
                    .filter(contractWorkflowEntity -> typeWorkflowIds.contains(contractWorkflowEntity.getId())).max((o1, o2) -> o2.getPriority() - o1.getPriority());
            if (first.isPresent()) {
                ContractWorkflowEntity contractWorkflowEntity = first.get();
                ProcessKeyTypeCache processKeyTypeCache = new ProcessKeyTypeCache();
                processKeyTypeCache.setProcessKey(contractWorkflowEntity.getProcessKey());
                processKeyTypeCache.setPriority(contractWorkflowEntity.getPriority());
                redisService.setHashObject(RedisKeyConstant.Business.APPROVAL_TYPE_PROCESS_PREFIX + contractTypeId, processKeyTypeCache);
            }
        });
        log.info("初始化合同类型对应的流程完成,共初始化合同类型: {} 个", typeMap.size());
    }
} 